#include "udp.h"
#include <QNetworkDatagram>
#include <QSqlDatabase>
#include <QSqlQuery>

#include "databasemanager.h"

Udp::Udp(QObject *parent) : QObject(parent)
{

}

Udp::~Udp()
{

}

void Udp::openAllPort()
{
    DatabaseManager& dbManager = DatabaseManager::getInstance();

    if (!dbManager.connectMysql())
    {
        qDebug() << "COM打开数据库失败";
        return;
    }
    QSqlQuery query(dbManager.getDatabase());
    query.clear();
    query.prepare("SELECT port_no FROM port where protocol = 3");
    if (query.exec())
    {
        while (query.next())
        {
            // 处理查询结果
            int port = query.value(0).toInt();
            QUdpSocket *udp_socket = new QUdpSocket(this);
            this->udp.insert(port, udp_socket);
            udp_socket->bind(port);
            connect(udp_socket, &QUdpSocket::readyRead, this, &Udp::dealMsg);
            qDebug() << "Udp端口" << port << "打开成功";
        }
    }

}

void Udp::sendData(const QString &ip, const quint16 &port, const QByteArray &data)
{
    // 1. 创建一个新的QUdpSocket实例专门用于发送
        QUdpSocket tempSendSocket;

        // 2. 发送数据
        // 不需要bind，除非你想指定发送的源端口
        qint64 bytesWritten = tempSendSocket.writeDatagram(data, QHostAddress(ip), port);

        if (bytesWritten == -1) {
            qDebug() << "发送UDP数据失败:" << tempSendSocket.errorString();
        } else {
            qDebug() << "成功发送" << bytesWritten << "字节到" << ip << ":" << port;
        }
        // tempSendSocket 会在函数结束时自动销毁
}

void Udp::dealMsg()
{
    QUdpSocket *udp_socket = qobject_cast<QUdpSocket*>(sender());
    if (!udp_socket) {return; }
    while (udp_socket->hasPendingDatagrams())
    {
        QNetworkDatagram datagram = udp_socket->receiveDatagram(); // 读取一个数据报
        // 如果需要，可以获取发送方的地址和端口
        // QHostAddress senderAddress = datagram.senderAddress();
        // quint16 senderPort = datagram.senderPort();

        QByteArray data = datagram.data(); // 获取数据内容

        QString str = QString::fromLocal8Bit(data); // 保证发送的非ASCII码的中文能够打印出来
        quint16 localListenPort = udp_socket->localPort();
        qDebug() << "接受方端口：" << localListenPort /*<< "接收方ip" << datagram.senderAddress()*/
                 << "发送方端口：" << datagram.senderPort()
                 << "发送的数据内容：" << /*data*/str;
        emit dataReceivedFromSocket(localListenPort, datagram.senderAddress(), datagram.senderPort(), data);
//        qDebug() << "UDP data received:" << data;
        // qDebug() << "From:" << senderAddress.toString() << ":" << senderPort;

        // 在这里处理接收到的 data ...
    }
}
